#pragma once

#include "common_definition.h"
#include "stm32f4xx_hal.h"
#include <algorithm>
#include <array>
#include <functional>
#include <gpio.hpp>
#include <limits>
#include <timer.hpp>
#include <tuple>
#include <type_traits>
#include <utility>


/**
 * 鉴于stm32的ADC不常用，这里就暂时不做优化
 */
// DMA配置很简单不需要改。用法如下：
// HAL_TIM_Base_Start(&htim2);
// HAL_ADC_Start(&hadc1);
// HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_value, 128);
// 不用开启中断，但是要触发定时器是要开的，定时器只要触发事件就行了

// namespace hal
// {
//     // 配置参数
//     inline constexpr uint32_t default_sampling_time = ADC_SAMPLETIME_480CYCLES;
//     inline constexpr uint32_t adc_resolution = ADC_RESOLUTION_12B;
//     inline constexpr uint32_t clock_prescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
//     inline constexpr uint32_t temperature_sensor_v25 = 760;// 25°C时电压值(mV)
//     inline constexpr float avg_slope = 2.5f;               // 温度斜率(mV/°C)
//     inline constexpr float vref_mv = 3300.0f;              // 参考电压(mV)
//
//     // 编译器标志，用于防止同一个引脚被多个通道复用
//     template<uint32_t GPIO_PortBase, uint16_t GPIO_Pin>
//     struct pin_owner {
//         static constexpr uint32_t adc_base = 0;
//         static constexpr uint32_t channel = 0;
//     };
//
//     // ADC引脚特性模板
//     template<uint32_t ADC_Base, uint32_t ADC_Channel>
//     struct adc_pin_traits {
//         static_assert(ADC_Base != 0, "Unsupported ADC channel configuration");
//     };
//
// // 引脚映射特化
// #define DEFINE_ADC_PIN(ADC_BASE, CHAN, PORT_PIN) \
//     template<>                                   \
//     struct adc_pin_traits<ADC_BASE, CHAN> {      \
//         using pin = PORT_PIN;                    \
//     }
//
//     // ADC1引脚映射
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_0, gpio::portA::pin0);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_1, gpio::portA::pin1);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_2, gpio::portA::pin2);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_3, gpio::portA::pin3);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_4, gpio::portA::pin4);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_5, gpio::portA::pin5);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_6, gpio::portA::pin6);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_7, gpio::portA::pin7);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_8, gpio::portB::pin0);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_9, gpio::portB::pin1);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_10, gpio::portC::pin0);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_11, gpio::portC::pin1);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_12, gpio::portC::pin2);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_13, gpio::portC::pin3);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_14, gpio::portC::pin4);
//     DEFINE_ADC_PIN(ADC1_BASE, ADC_CHANNEL_15, gpio::portC::pin5);
//
//     // ADC2引脚映射
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_0, gpio::portA::pin0);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_1, gpio::portA::pin1);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_2, gpio::portA::pin2);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_3, gpio::portA::pin3);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_4, gpio::portA::pin4);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_5, gpio::portA::pin5);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_6, gpio::portA::pin6);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_7, gpio::portA::pin7);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_8, gpio::portB::pin0);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_9, gpio::portB::pin1);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_10, gpio::portC::pin0);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_11, gpio::portC::pin1);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_12, gpio::portC::pin2);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_13, gpio::portC::pin3);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_14, gpio::portC::pin4);
//     DEFINE_ADC_PIN(ADC2_BASE, ADC_CHANNEL_15, gpio::portC::pin5);
//
//     // ADC3引脚映射
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_0, gpio::portA::pin0);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_1, gpio::portA::pin1);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_2, gpio::portA::pin2);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_3, gpio::portA::pin3);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_4, gpio::portA::pin4);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_5, gpio::portA::pin5);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_6, gpio::portA::pin6);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_7, gpio::portA::pin7);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_8, gpio::portB::pin0);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_9, gpio::portB::pin1);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_10, gpio::portC::pin0);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_11, gpio::portC::pin1);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_12, gpio::portC::pin2);
//     DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_13, gpio::portC::pin3);
//     // DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_14, gpio::portC::pin4);
//     // DEFINE_ADC_PIN(ADC3_BASE, ADC_CHANNEL_15, gpio::portC::pin5);
//
//
//
//
//     // 主ADC类模板
//     template<uint32_t ADC_Base>
//     class adc
//     {
//         static inline ADC_HandleTypeDef hadc{};
//
//         ALWAYS_INLINE static constexpr ADC_TypeDef *instance()
//         {
//             return reinterpret_cast<ADC_TypeDef *>(ADC_Base);
//         }
//
//          ALWAYS_INLINE static void enable_clock()
//         {
//             if constexpr (ADC_Base == ADC1_BASE) {
//                 __HAL_RCC_ADC1_CLK_ENABLE();
//             } else if constexpr (ADC_Base == ADC2_BASE) {
//                 __HAL_RCC_ADC2_CLK_ENABLE();
//             } else if constexpr (ADC_Base == ADC3_BASE) {
//                 __HAL_RCC_ADC3_CLK_ENABLE();
//             }
//         }
//
//         ALWAYS_INLINE static void init_common( const FunctionalState continuous_enable,const uint32_t ext_trigger, const uint32_t trigger_edge)
//         {
//             enable_clock();
//
//             hadc.Instance = instance();
//             hadc.Init.ClockPrescaler = clock_prescaler;
//             hadc.Init.Resolution = adc_resolution;
//             hadc.Init.ScanConvMode = DISABLE;
//             hadc.Init.ContinuousConvMode = ENABLE;// 连续触发，确保中断里转换依次后，还能再次启动
//             hadc.Init.DiscontinuousConvMode = DISABLE;
//             hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
//             hadc.Init.NbrOfConversion = 1;
//             hadc.Init.DMAContinuousRequests = DISABLE;
//             hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
//             hadc.Init.ExternalTrigConv = ext_trigger;
//             hadc.Init.ExternalTrigConvEdge = trigger_edge;
//
//             HAL_ADC_Init(&hadc);
//         }
//
//
//     public:
//         ALWAYS_INLINE static ADC_HandleTypeDef *get_handle() { return &hadc; }
//
//         /**
//          *  通道类模板
//          * @tparam ADC_Channel ADC通道
//          * @note 目前仅用作TIM2触发ADC产生中断
//          */
//         template<uint32_t ADC_Channel>
//         class channel
//         {
//         public:
//             ALWAYS_INLINE static void init(const uint32_t sampling_time = default_sampling_time,
//                              const uint32_t ext_trigger = ADC_EXTERNALTRIGCONV_T2_TRGO,
//                              const uint32_t trigger_edge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING)
//             {
//                 // 配置GPIO
//                 using traits = adc_pin_traits<ADC_Base, ADC_Channel>;
//                 using adc_pin = typename traits::pin;
//                 adc_pin cfg;
//                 cfg.initializer().mode.analog().pull.none();
//
//                 // 初始化ADC外设（仅需一次）
//                 init_common(DISABLE,ext_trigger, trigger_edge);
//
//                 // 配置通道
//                 ADC_ChannelConfTypeDef sConfig{};
//                 sConfig.Channel = ADC_Channel;
//                 sConfig.Rank = 1;
//                 sConfig.SamplingTime = sampling_time;
//                 sConfig.Offset = 0;
//
//                 HAL_ADC_ConfigChannel(&adc::hadc, &sConfig);
//             }
//
//             ALWAYS_INLINE static void init_IT(const uint32_t psc, const uint32_t arr,const uint32_t sampling_time = default_sampling_time,
//                              const uint32_t ext_trigger = ADC_EXTERNALTRIGCONV_T2_TRGO,
//                              const uint32_t trigger_edge = ADC_EXTERNALTRIGCONVEDGE_RISINGFALLING)
//             {
//                 // 配置GPIO
//                 using traits = adc_pin_traits<ADC_Base, ADC_Channel>;
//                 using adc_pin = typename traits::pin;
//                 adc_pin cfg;
//                 cfg.initializer().mode.analog().pull.none();
//
//                 // 初始化ADC外设
//                 init_common(ENABLE,ext_trigger, trigger_edge);
//
//                 // 配置中断
//                 timer2::init(psc,arr);
//                 HAL_NVIC_SetPriority(ADC_IRQn, 2, 0);
//                 HAL_NVIC_EnableIRQ(ADC_IRQn);
//
//                 // 配置通道
//                 ADC_ChannelConfTypeDef sConfig{};
//                 sConfig.Channel = ADC_Channel;
//                 sConfig.Rank = 1;
//                 sConfig.SamplingTime = sampling_time;
//                 sConfig.Offset = 0;
//                 HAL_ADC_ConfigChannel(&adc::hadc, &sConfig);
//             }
//
//
//             ALWAYS_INLINE static uint16_t read()
//             {
//                 HAL_ADC_Start(&adc::hadc);
//                 HAL_ADC_PollForConversion(&adc::hadc, 10);
//                 return HAL_ADC_GetValue(&adc::hadc);
//             }
//
//             ALWAYS_INLINE static  uint16_t read_IT()
//             {
//                 return HAL_ADC_GetValue(&adc::hadc);
//             }
//
//             static uint16_t read_average(uint8_t samples = 16)
//             {
//                 uint32_t sum = 0;
//                 samples = (samples == 0) ? 1 : samples;
//
//                 for (uint8_t i = 0; i < samples; i++) {
//                     sum += read();
//                     if (i < samples - 1) HAL_Delay(1);
//                 }
//                 return static_cast<uint16_t>(sum / samples);
//             }
//
//             // ADC通用控制方法
//             ALWAYS_INLINE static void start_IT()
//             {
//                 timer2::start();
//                 HAL_ADC_Start_IT(&hadc);
//             }
//
//             ALWAYS_INLINE static void stop_IT()
//             {
//                 timer2::stop();
//                 HAL_ADC_Stop_IT(&hadc);
//             }
//         };
//
//         // 通道别名定义
//         using channel0 = channel<ADC_CHANNEL_0>;
//         using channel1 = channel<ADC_CHANNEL_1>;
//         using channel2 = channel<ADC_CHANNEL_2>;
//         using channel3 = channel<ADC_CHANNEL_3>;
//         using channel4 = channel<ADC_CHANNEL_4>;
//         using channel5 = channel<ADC_CHANNEL_5>;
//         using channel6 = channel<ADC_CHANNEL_6>;
//         using channel7 = channel<ADC_CHANNEL_7>;
//         using channel8 = channel<ADC_CHANNEL_8>;
//         using channel9 = channel<ADC_CHANNEL_9>;
//         using channel10 = channel<ADC_CHANNEL_10>;
//         using channel11 = channel<ADC_CHANNEL_11>;
//         using channel12 = channel<ADC_CHANNEL_12>;
//         using channel13 = channel<ADC_CHANNEL_13>;
//         using channel14 = channel<ADC_CHANNEL_14>;
//         using channel15 = channel<ADC_CHANNEL_15>;
//         using channel16 = channel<ADC_CHANNEL_16>;
//         using channel17 = channel<ADC_CHANNEL_17>;
//         using channel18 = channel<ADC_CHANNEL_18>;
//
//         // 温度传感器专用（仅ADC1）
//         template<typename T = std::enable_if_t<ADC_Base == ADC1_BASE, void>>
//         class temperature_sensor
//         {
//         public:
//             ALWAYS_INLINE static void init(const uint32_t sampling_time = ADC_SAMPLETIME_480CYCLES)
//             {
//                 init_common(DISABLE,ADC_SOFTWARE_START, ADC_EXTERNALTRIGCONVEDGE_NONE);
//
//                 // 使能温度传感器
//                 ADC->CCR |= ADC_CCR_TSVREFE;
//
//                 // 配置通道
//                 ADC_ChannelConfTypeDef chcfg{};
//                 chcfg.Channel = ADC_CHANNEL_TEMPSENSOR;
//                 chcfg.Rank = 1;
//                 chcfg.SamplingTime = sampling_time;
//                 chcfg.Offset = 0;
//
//                 HAL_ADC_ConfigChannel(&adc::hadc, &chcfg);
//             }
//
//             ALWAYS_INLINE static float read()
//             {
//                 HAL_ADC_Start(&adc::hadc);
//                 HAL_ADC_PollForConversion(&adc::hadc, 10);
//                 const float sense_mv = static_cast<float>(HAL_ADC_GetValue(&adc::hadc)) * vref_mv / 4095.0f;
//                 return (sense_mv - temperature_sensor_v25) / avg_slope + 25.0f;
//             }
//         };
//
//         // ADC通用控制方法
//         ALWAYS_INLINE static void start()
//         {
//             timer2::start();
//             HAL_ADC_Start_IT(&hadc);
//         }
//
//         ALWAYS_INLINE static void stop()
//         {
//             timer2::stop();
//             HAL_ADC_Stop_IT(&hadc);
//         }
//     };
//
// }// namespace hal

// 导出ADC类型

namespace hal::detail_adc
{

    template<uint32_t ADC_Base>
    class adcCommon
    {
    public:
        static inline ADC_HandleTypeDef hadc{};

        // ADC通用控制方法
        //  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC1_DATA, sizeof(ADC1_DATA) / sizeof(ADC1_DATA[0]));
        ALWAYS_INLINE static void start(uint32_t *pData, const uint32_t Length)
        {
            HAL_ADC_Start_DMA(&hadc, pData, Length);
        }

        ALWAYS_INLINE static void stop()
        {

        }
    };

    template<uint32_t ADC_Base>
    class adcConfig{};

    template<>
    class adcConfig<ADC1_BASE>:public adcCommon<ADC1_BASE>
    {
        static inline bool adc_complete = false;
    public:
        static inline DMA_HandleTypeDef hdma_adc1{};
        static inline TIM_HandleTypeDef htim2{};

        static void handleInterrupt()
        {
            if (__HAL_DMA_GET_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1))) {
                // 清除传输完成标志
                __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1));
                // fuck interrupt
                __HAL_DMA_DISABLE_IT(&hdma_adc1,DMA_IT_DME | DMA_IT_HT | DMA_IT_FE | DMA_IT_TE);
                HAL_TIM_Base_Stop(&htim2);
                HAL_ADC_Stop_DMA(&hadc);
                __HAL_DMA_DISABLE_IT(&hdma_adc1,DMA_IT_TC);
                adc_complete = true;

            }
        }
        static bool getDMAComplete()
        {
            if (!adc_complete)
                return false;
            adc_complete = false;
            return true;
        }

        template<typename T,std::size_t size>
        static void start(std::array<T,size>& adcBuffer)
        {
            // 重置完成标志
            adc_complete = false;
            // __HAL_DMA_ENABLE_IT(&hdma_adc1,DMA_IT_TC);
            hdma_adc1.Instance->CR |= DMA_IT_TC;

            HAL_ADC_Start_DMA(&hadc, reinterpret_cast<uint32_t *>(adcBuffer.data()), size);
            HAL_TIM_Base_Start(&htim2);
        }

        static void stop()
        {
            __HAL_DMA_CLEAR_FLAG(&hdma_adc1, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_adc1));
            __HAL_DMA_DISABLE_IT(&hdma_adc1,DMA_IT_DME | DMA_IT_HT | DMA_IT_FE | DMA_IT_TE);
            HAL_TIM_Base_Stop(&htim2);
            HAL_ADC_Stop_DMA(&hadc);
            __HAL_DMA_DISABLE_IT(&hdma_adc1,DMA_IT_TC);
        }

        static void set_sample_rate(const uint32_t psc, const uint32_t arr)
        {
            __HAL_TIM_SET_PRESCALER(&htim2,psc);
            __HAL_TIM_SET_AUTORELOAD(&htim2,arr);
        }
        static void set_sample_rate(const uint32_t freq)
        {
            if (freq>=2'400'000) {
#ifdef ENABLE_DEBUG
                __BKPT();
#endif
                return;
            }
            // 计算最小预分频值（避免ARR溢出）
            constexpr uint32_t TIM2_CLK_FREQ = 84000000;
            const uint32_t cycles_per_sec = TIM2_CLK_FREQ / freq;
            const uint32_t psc = (cycles_per_sec - 1) / 65535 + 1;

            // 计算对应ARR值（考虑整数除法截断）
            const uint32_t arr = (cycles_per_sec / psc) - 1;

            __HAL_TIM_SET_PRESCALER(&htim2,psc);
            __HAL_TIM_SET_AUTORELOAD(&htim2,arr);
        }


        static void init()
        {
            /*****************gpio********************/

            GPIO_InitTypeDef GPIO_InitStruct = {};
            __HAL_RCC_ADC1_CLK_ENABLE();
            __HAL_RCC_DMA2_CLK_ENABLE();
            __HAL_RCC_GPIOA_CLK_ENABLE();

            /**ADC1 GPIO Configuration
                PA0-WKUP     ------> ADC1_IN0
                PA1     ------> ADC1_IN1
                */
            GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
            GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
            GPIO_InitStruct.Pull = GPIO_NOPULL;
            HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
            /* ADC1 DMA Init */
            /* ADC1 Init */
            hdma_adc1.Instance = DMA2_Stream0;
            hdma_adc1.Init.Channel = DMA_CHANNEL_0;
            hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
            hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
            hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
            hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
            hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
            hdma_adc1.Init.Mode = DMA_CIRCULAR;// 普通模式
            hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
            hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
            HAL_DMA_Init(&hdma_adc1);
            __HAL_LINKDMA(&hadc, DMA_Handle, hdma_adc1);
            // 关闭不必要的中断
            __HAL_DMA_DISABLE_IT(&hdma_adc1,DMA_IT_DME | DMA_IT_HT | DMA_IT_FE | DMA_IT_TE);
            /*****************DMA********************/
            HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 3, 0);
            HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

            /*****************ADC1*****************/

            hadc.Instance = ADC1;
            hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
            hadc.Init.Resolution = ADC_RESOLUTION_12B;
            hadc.Init.ScanConvMode = ENABLE;
            hadc.Init.ContinuousConvMode = ENABLE;
            hadc.Init.DiscontinuousConvMode = DISABLE;
            hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
            hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
            hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
            hadc.Init.NbrOfConversion = 2;
            hadc.Init.DMAContinuousRequests = ENABLE;// DMA非连续请求
            hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
            HAL_ADC_Init(&hadc);

            // 禁用ADC中断
            __HAL_ADC_DISABLE_IT(&hadc, ADC_IT_EOC| ADC_IT_AWD| ADC_IT_OVR| ADC_IT_JEOC);

            ADC_ChannelConfTypeDef sConfig = {};
            sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;

            sConfig.Channel = ADC_CHANNEL_0;
            sConfig.Rank = 1;
            HAL_ADC_ConfigChannel(&hadc, &sConfig);

            sConfig.Channel = ADC_CHANNEL_1;
            sConfig.Rank = 2;
            HAL_ADC_ConfigChannel(&hadc, &sConfig);

            /***************timer*****************/
            __HAL_RCC_TIM2_CLK_ENABLE();
            TIM_ClockConfigTypeDef sClockSourceConfig = {};
            TIM_MasterConfigTypeDef sMasterConfig = {};
            htim2.Instance = TIM2;
            htim2.Init.Prescaler = 5;//80K
            htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
            htim2.Init.Period = 41;
            htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
            htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
            HAL_TIM_Base_Init(&htim2);
            sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
            HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig);
            sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
            sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
            HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
            /****************timer 开启******************/
            // HAL_TIM_Base_Start(&htim2);
        }
    };


    // 温度传感器专用（仅ADC1）
    class temperature_sensor
    {
        static inline ADC_HandleTypeDef hadc{};
        static inline  constexpr uint32_t temperature_sensor_v25 = 760;       // 25°C时电压值(mV)
        static inline constexpr float avg_slope = 2.5f;               // 温度斜率(mV/°C)
        static inline constexpr float vref_mv = 3300.0f;              // 参考电压(mV)
    public:
        ALWAYS_INLINE static void init(const uint32_t sampling_time = ADC_SAMPLETIME_480CYCLES)
        {
            __HAL_RCC_ADC1_CLK_ENABLE();

            hadc.Instance = ADC1;
            hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
            hadc.Init.Resolution = ADC_RESOLUTION_12B;
            hadc.Init.ScanConvMode = DISABLE;
            hadc.Init.ContinuousConvMode = ENABLE;// 连续触发，确保中断里转换依次后，还能再次启动
            hadc.Init.DiscontinuousConvMode = DISABLE;
            hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
            hadc.Init.NbrOfConversion = 1;
            hadc.Init.DMAContinuousRequests = DISABLE;
            hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
            hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
            hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

            HAL_ADC_Init(&hadc);

            // 使能温度传感器
            ADC->CCR |= ADC_CCR_TSVREFE;

            // 配置通道
            ADC_ChannelConfTypeDef chcfg{};
            chcfg.Channel = ADC_CHANNEL_TEMPSENSOR;
            chcfg.Rank = 1;
            chcfg.SamplingTime = sampling_time;
            chcfg.Offset = 0;

            HAL_ADC_ConfigChannel(&hadc, &chcfg);
        }

        ALWAYS_INLINE static float read()
        {
            HAL_ADC_Start(&hadc);
            HAL_ADC_PollForConversion(&hadc, 10);
            const float sense_mv = static_cast<float>(HAL_ADC_GetValue(&hadc)) * vref_mv / 4095.0f;
            return (sense_mv - temperature_sensor_v25) / avg_slope + 25.0f;
        }
    };
}

namespace hal
{
    using adc1 = detail_adc::adcConfig<ADC1_BASE>;
    using adc2 = detail_adc::adcConfig<ADC2_BASE>;
    // using adc3 = adc<ADC3_BASE>;
    using adc_temperature = detail_adc::temperature_sensor;
}// namespace hal
